﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

using CSF.BusinessCore.Data;
using Ict.DataAccess;

namespace CSF.BusinessCore.BLL
{
    public abstract class TransactionConfigLogic<TEntity> : TransactionLogic<TEntity>
        where TEntity : TransactionConfig, new()
    {
        /// <summary>
        /// 根据代码(主键）读取数据库记录并填充到一个数据类实例
        /// </summary>
        /// <param name="code">代码</param>
        /// <returns>数据类实例</returns>
        public TEntity GetOneByCode(string code)
        {
            var q = from p in DataContext.Select<TEntity>()
                    where p.Code == code
                    select p;
            return q.First();
        }

        /// <summary>
        /// 取所有活动（可用的）的数据列表
        /// </summary>
        /// <returns>数据列表</returns>
        public List<TEntity> GetEnable()
        {
            var q = from p in DataContext.Select<TEntity>()
                    where !p.IsDisable || p.IsDisable == null
                    orderby p.Sequence
                    select p;
            return q.ToList();
        }

        /// <summary>
        /// 取所有活动（可用的）的数据列表
        /// </summary>
        /// <returns>数据列表</returns>
        public List<TEntity> GetDisable()
        {
            var q = from p in DataContext.Select<TEntity>()
                    where p.IsDisable
                    orderby p.Sequence
                    select p;
            return q.ToList();
        }

        /// <summary>
        /// 取代码或名字以指定关键字开头的数据列表
        /// </summary>
        /// <param name="keyword">关键字</param>
        /// <returns>数据列表</returns>
        public List<TEntity> GetStartsWith(string keyword, bool isDisable)
        {
            if (isDisable)
            {
                var q = from p in DataContext.Select<TEntity>()
                        where (p.Code.StartsWith(keyword) ||
                            p.Name1.StartsWith(keyword) ||
                            p.Name2.StartsWith(keyword) ||
                            p.Name3.StartsWith(keyword))
                            && p.IsDisable
                        select p;
                return q.ToList();
            }
            else
            {
                var q = from p in DataContext.Select<TEntity>()
                        where (p.Code.StartsWith(keyword) ||
                            p.Name1.StartsWith(keyword) ||
                            p.Name2.StartsWith(keyword) ||
                            p.Name3.StartsWith(keyword))
                            && !p.IsDisable
                        select p;
                return q.ToList();
            }
        }

        /// <summary>
        /// 停用/启用一组数据对象
        /// </summary>
        public int SetDisable(IEnumerable<int> ids, bool isDisable, string modifyBy)
        {
            int count = 0;
            TEntity t = new TEntity();
            t.IsDisable = isDisable;
            t.ModifyBy = modifyBy;

            using (Executor exec = DataContext.CreateExecutor())
            {
                try
                {
                    exec.BeginTransaction();
                    foreach (var id in ids)
                    {
                        base.Update(t, p => new { IsDisable = p.IsDisable, p.ModifyBy, p.ModifyTime }, p => p.Id == id, exec);
                    }
                    exec.CommitTransaction();
                }
                catch (Exception)
                {
                    exec.RollbackTransaction();
                    throw;
                }
            }

            return count;
        }

        /// <summary>
        /// 停用某个数据对象
        /// </summary>
        /// <param name="t">数据对象实例</param>
        public bool Disable(TEntity t)
        {
            if (t.Id <= 0)
                throw new NoIdSpecifiedException();

            t.IsDisable = true;
            int count = base.Update(t, p => new { IsDisable = p.IsDisable, p.ModifyBy, p.ModifyTime }, p => p.Id == t.Id);
            return count > 0;
        }


        /// <summary>
        /// 恢复某个数据对象
        /// </summary>
        /// <param name="t">数据对象实例</param>
        public bool Enable(TEntity t)
        {
            if (t.Id <= 0)
                throw new NoIdSpecifiedException();

            t.IsDisable = false;
            int count = base.Update(t, p => new { IsDisable = p.IsDisable, p.ModifyBy, p.ModifyTime }, p => p.Id == t.Id);
            return count > 0;
        }
    }
}
